package net.fenghaitao.imports;

import net.fenghaitao.context.ImportContext;
import net.fenghaitao.exception.AutoExcelException;
import net.fenghaitao.parameters.ImportPara;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Kephon
 */
public class ExcelDataHandler {
    
    private final ImportContext importContext;

    public ExcelDataHandler(ImportContext importContext) {
        this.importContext = importContext;
    }

    public void process(String filename) {
        try (InputStream inputStream = new FileInputStream(filename);
             Workbook workbook = new XSSFWorkbook(inputStream)) {

            List<Map<String, Object>> dataList = new ArrayList<>();

            for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
                
                // 获取工作表
                Sheet sheet = workbook.getSheetAt(sheetNum);

                if (importContext.initSheet(sheet.getSheetName())) {

                    ImportPara curImportPara = importContext.getCurImportPara();
                    int titleIndex = curImportPara.getTitleIndex();
                    int dataStartIndex = curImportPara.getDataStartIndex();

                    Map<Integer, String> columnFieldNames = new HashMap<>(16);

                    // 迭代每一行并处理数据
                    for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {

                        // excel行
                        Row row = sheet.getRow(rowNum);
                        
                        if (null == row) {
                            continue;
                        }

                        // 标题行
                        if (rowNum == titleIndex) {

                            // 导入表头映射字段
                            Map<String, String> fieldNameMap = importContext.getSheetFieldNames().get(importContext.getCurSheetIndex());
                            // 使用迭代器遍历每个单元格
                            for (Cell cell : row) {
                                // 获取单元格数据
                                Object cellValue = getCellValue(workbook, cell.getColumnIndex(), row);
                                if (null != cellValue) {
                                    String strValue = cellValue.toString();
                                    // 设置字段数据
                                    String fieldName = fieldNameMap.getOrDefault(strValue, strValue);
                                    columnFieldNames.put(cell.getColumnIndex(), fieldName);
                                }
                            }

                        }

                        // 表体数据行
                        else if (rowNum >= dataStartIndex) {
                            Map<String, Object> dataRow = new HashMap<>(16);

                            for (Cell cell : row) {
                                if (columnFieldNames.containsKey(cell.getColumnIndex())) {
                                    dataRow.put(columnFieldNames.get(cell.getColumnIndex()), getCellValue(workbook, cell.getColumnIndex(), row));
                                }
                            }

                            // 添加到数据列表
                            dataList.add(dataRow);
                        }

                    }
                    
                }
                
            }

            importContext.getDataSet().get(importContext.getCurSheetName()).addAll(dataList);
        } catch (Exception e) {
            e.printStackTrace();
            throw new AutoExcelException(e);
        }
    }

    private Object getCellValue(Workbook workbook, int columnNumber, Row row) {
        Cell cell = row.getCell(columnNumber, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);

        CellType cellType = cell.getCellType();

        switch (cellType) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                // 获取日期单元格的数值
                if (DateUtil.isCellDateFormatted(cell)) {
                    return DateUtil.getJavaDate(cell.getNumericCellValue());
                } else {
                    return cell.getNumericCellValue();
                }
            case BOOLEAN:
                return cell.getBooleanCellValue();
            case BLANK:
                return null;
            case FORMULA:
                FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();

                // 通过计算器计算公式结果
                CellValue cellValue = evaluator.evaluate(cell);
                
                switch (cellValue.getCellType()) {
                    case BOOLEAN:
                        return cellValue.getBooleanValue();
                    case NUMERIC:
                        return cellValue.getNumberValue();
                    case STRING:
                    default:
                        return cellValue.getStringValue();
                }
            default:
                return cell.toString();
        }
    }

}
